grammar Cymbol;

//@parser::header {
//  package antlr4;
//}

compilationUnit
    :   (methodDeclaration | varDeclaration)+
    ;

// START: method
methodDeclaration
    :   type ID '(' formalParameters? ')' block
    ;
// END: method

formalParameters
    :   type ID (',' type ID)*
    ;

type:   'float'
    |   'int'
    |	'void'
    ;

// START: block
block
    :   '{' statement* '}'
    ;
// END: block

// START: var
varDeclaration
    :   type ID ('=' expression)? ';'
    ;
// END: var

statement
    :   block
    |	varDeclaration
    |   RETURN expression? ';'
    |   postfixExpression ('=' expression)? ';' // handles function calls like f(i);
    ;

expressionList
    :   expression (',' expression)*
    |
    ;

expression
    :   addExpression
    ;

addExpression
	:	postfixExpression ('+' postfixExpression)*
	;

// START: call
postfixExpression
    :   primary ( lp='(' expressionList ')' )? // 参考代码里末尾是“*”，这里为了方便我改为“?”
    ;
// END: call

primary
    :   ID
    |   INT
    |   '(' expression ')'
    ;

// LEXER RULES

RETURN 
    : 'return'
    ;

ID  :   LETTER (LETTER | '0'..'9')*
    ;

fragment
LETTER  :   ('a'..'z' | 'A'..'Z')
    ;

INT :   '0'..'9'+
    ;

WS  :   (' '|'\r'|'\t'|'\n') -> skip
    ;

SL_COMMENT
    :   '//' ~('\r'|'\n')* '\r'? '\n' -> skip
    ;
